package com.itheima.w_util;

import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;

import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;

public class ReflectUtils {

    private static final String GET_METHOD_NAME="get";

    //获取对象上的泛型信息
    public static Class getGenerateType(int index,Object obj) {
        ParameterizedType parameterizedType = (ParameterizedType) obj.getClass().getGenericSuperclass();
        Class actualTypeArgument = (Class) parameterizedType.getActualTypeArguments()[index];
        return actualTypeArgument;
    }

    public static <T> T getField(T dto,String fieldName,Class<T> returnType){
        return getField(dto,fieldName,returnType,true);
    }

    public static <T> T getField(Object dto,String fieldName,Class<T> returnType,boolean isJoin){
        String methodName=isJoin? StrUtil.join("",GET_METHOD_NAME,StrUtil.upperFirst(fieldName)):fieldName;
        Object invoke = invoke(dto, methodName,returnType,null);
        return (T) invoke;
    }

    private static <T> Object invoke(Object obj, String methodName, Class<T> returnType, Object... params) {
        Method method=ReflectUtil.getMethod(obj.getClass(), methodName, getParameterTypes(params));
        if (method == null) {
            throw new RuntimeException("cannot find:"+methodName);
        }
        Object invoke = ReflectUtil.invoke(obj, method, params);
        if (returnType.isInstance(invoke)) {
            return invoke;
        }
        else {
            throw new RuntimeException("Return value cannot be converted to "+returnType.getName());
        }
    }

    private static Class<?>[] getParameterTypes(Object[] args) {
        if (args==null || args.length==0){
            return new Class[0];
        }
        Class<?>[] parameterTypes = new Class<?>[args.length];
        for (int i = 0; i < args.length; i++) {
            parameterTypes[i]=args[i]==null?null:args[i].getClass();
        }
        return parameterTypes;
    }


}
